package com.genauth.sys.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.genauth.sys.config.MySessionListener;
import com.genauth.sys.config.MyWebSocket;
import com.genauth.sys.entity.PageRA;
import com.genauth.sys.entity.PageResponse;
import com.genauth.sys.entity.RoleBean;
import com.genauth.sys.entity.UserBean;
import com.genauth.sys.service.SubMenuService;
import com.genauth.sys.service.UserService;
import com.genauth.sys.util.CommonUtils;
import com.genauth.sys.util.PageConstants;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping(value = "/genauth/userManage")
public class UserManageAction {
	@Resource
	private UserService userService;
	@Resource
	private SubMenuService subMenuService;

	private Logger logger = LoggerFactory.getLogger(UserManageAction.class);

	@ResponseBody
	@RequestMapping(value = "/userLogin.do", produces = "application/json;charset=UTF-8",method = {RequestMethod.POST})
	public PageResponse userLogin(HttpServletRequest request, @RequestBody UserBean user) throws Exception {
		PageResponse result = new PageResponse();
		logger.info("UserManageAction.userLogin: user.name => " + user.getUserName());
		Map<String, Object> res = new HashMap<>();
		if (StringUtils.isEmpty(user.getUserName()) || StringUtils.isEmpty(user.getUserPassword())) {
			res.put("error", PageConstants.LOGIN_ERROR_EMPTY);
		} else {
			user.setUserName(URLDecoder.decode(user.getUserName(), "UTF-8"));
			List<UserBean> users = userService.userLogin(user);
			if (users.size() == 0) {
				res.put("error", PageConstants.LOGIN_ERROR_NOUSER);
			} else if (users.size() > 1) {
				res.put("error", PageConstants.LOGIN_ERROR_USERINFOERROR);
			} else {
				res.put("token", request.getSession().getId());

				UserBean cuser = users.get(0);
				request.getSession().setAttribute("currentUser", cuser);
				//把前台要求的左侧菜单加载出来
				List<Map<String,Object>> userMenus = userService.generateUserMenu(cuser.getUserId());
				res.put("menus",userMenus);
				// 用来统计系统所有登陆用户
				Map<String, Object> loginUsers = MySessionListener.getAllSession();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				if (loginUsers.containsKey(request.getSession().getId())) {
					Map<String, Object> loginUser = (Map<String, Object>) loginUsers.get(request.getSession().getId());
					sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
					loginUser.put("loginTime", sdf.format(new Date()));
					loginUser.put("loginIP", request.getRemoteAddr());
				}
			}
		}
		result.setRspData(res);
		return result;
	}

	@ResponseBody
	@RequestMapping(value = "/getLoginUserInfo.do", produces = "application/json;charset=UTF-8", method = {RequestMethod.POST})
	public PageResponse getLoginUserInfo(HttpServletRequest request,String token){
		PageResponse result = new PageResponse();
		if(request.getSession().getId().equals(token)){
			UserBean user = (UserBean) request.getSession().getAttribute("currentUser");
			JSONObject userInfo = JSON.parseObject(JSON.toJSONString(user));
			//把前台要求的左侧菜单加载出来
			List<Map<String,Object>> userMenus = userService.generateUserMenu(user.getUserId());
			userInfo.put("menus",userMenus);
			result.setRspData(userInfo);
		}else{
			result.setCode(PageConstants.PGECODE_LOGINEXPIRED);
		}
		return result;
	}

	@ResponseBody
	@RequestMapping(value = "/userLogout.do", produces = "application/json;charset=UTF-8")
	public PageResponse userLogout(HttpServletRequest request) throws Exception {
		logger.info("UserManageAction.userLogout: ");
		request.getSession().removeAttribute("currentUser");
		return new PageResponse();
	}

	@ResponseBody
	@RequestMapping(value = "/queryUser.do", produces = "application/json;charset=UTF-8")
	public PageResponse queryUser(HttpServletRequest request, String userName) throws Exception {
		PageResponse result = new PageResponse();
		// post请求过来的中文， 经过config.js里的http配置已经进行了UTF-8转码，这是还是要解码下。
		if (StringUtils.isNotEmpty(userName)) {
			userName = java.net.URLDecoder.decode(userName, "UTF-8");
		}

		logger.info("UserManageAction.queryUser: userName => " + userName);
		List<UserBean> queryRes = userService.queryUserByName(userName);
		logger.info("UserManageAction.queryUser: " + queryRes.size());
		result.setRspData(queryRes);
		return result;
	}

	@ResponseBody
	@RequestMapping(value = "/modifyUser.do", produces = "application/json;charset=UTF-8")
	public PageResponse modifyUser(UserBean user, Boolean resetPass) throws Exception {
		PageResponse resp = new PageResponse();
		if (StringUtils.isNotEmpty(user.getUserName())) {
			user.setUserName(java.net.URLDecoder.decode(user.getUserName(), "UTF-8"));
		}
		if (StringUtils.isNotEmpty(user.getUserRealname())) {
			user.setUserRealname(java.net.URLDecoder.decode(user.getUserRealname(), "UTF-8"));
		}
		logger.info("UserManageAction.modifyUser: userId => " + user.getUserId() + ";userName => " + user.getUserName()
				+ ";resetPass => " + resetPass);
		Map<String, Object> resInfo = new HashMap<>();
		int optRes;
		if (StringUtils.isEmpty(user.getUserId())) {
			try {
				optRes = userService.addUser(user);
				if (optRes > 0) {
					resInfo.put("code", "1");
					resInfo.put("msg", "用户新增成功");
				}
			} catch (Exception e) {
				logger.warn("用户新增失败;" + e);
				resInfo.put("msg", "用户新增失败;请确认没有重复用户或联系管理员");
			}
		} else {
			try {
				if (null != resetPass && resetPass) {
					optRes = userService.updateUserAndResetPass(user);
				} else {
					optRes = userService.updateUser(user);
				}
				if (optRes > 0) {
					resInfo.put("code", "1");
					resInfo.put("msg", "用户修改成功");
				}
			} catch (Exception e) {
				logger.warn("用户修改失败;" + e);
				resInfo.put("msg", "用户修改失败" + e.getMessage());
			}
		}
		resp.setRspData(resInfo);
		return resp;
	}

	@ResponseBody
	@RequestMapping(value = "/deleteUser.do", produces = "application/json;charset=UTF-8")
	public PageResponse deleteUser(String userId) throws Exception {
		PageResponse resp = new PageResponse();
		Map<String, Object> res = new HashMap<>();
		logger.info("UserManageAction.deleteUser: userId => " + userId);
		int result = userService.deleteUser(userId);
		if (result > 0) {
			res.put("msg", "用户删除成功");
		}
		resp.setRspData(res);
		return resp;
	}

	@ResponseBody
	@RequestMapping(value = "/queryRole.do", produces = "application/json;charset=UTF-8")
	public PageResponse queryRole() throws Exception {
		logger.info("UserManageAction.queryRole:");
		PageResponse resp = new PageResponse();
		List<RoleBean> roles = userService.queryRole();
		logger.info("UserManageAction.queryRole: " + roles.size());
		resp.setRspData(roles);
		return resp;
	}

	@ResponseBody
	@RequestMapping(value = "/deleteRole.do", produces = "application/json;charset=UTF-8")
	public PageResponse deleteRole(String roles) throws Exception {
		PageResponse resp = new PageResponse();

		Map<String, Object> res = new HashMap<>();
		logger.info("UserManageAction.deleteRole: roles => " + roles);
		int result = 0;
		for (String roleId : roles.split("\\|")) {
			if (StringUtils.isNotEmpty(roleId)) {
				result += userService.delelteRole(roleId);
			}
		}
		resp.setRspData("成功删除" + result + "个角色");
		return resp;
	}

	/**
	 * 加载所有的菜单。这个东东变化很少，加个缓存。
	 *
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@Cacheable(value = "sysCache", key = "'user.querySubMenu'")
	@RequestMapping(value = "/querySubMenu.do", produces = "application/json;charset=UTF-8")
	public PageResponse querySubMenu() throws Exception {
		PageResponse result = new PageResponse();
		List<Map<String, Object>> res = userService.querySubMenu();
		logger.info("UserManageAction.querySubMenu: res = " + JSONArray.toJSONString(res));
		result.setRspData(res);
		return result;
	}

	@ResponseBody
	@Transactional
	@RequestMapping(value = "/updateRA.do", produces = "application/json;charset=UTF-8")
	public PageResponse updateRA(PageRA ra) throws Exception {
		logger.info("UserManageAction.updateRA: "+ra.toString());
		PageResponse result = new PageResponse();
		// 删除角色所有权限。
		String role = ra.getRole();
		String menusInfo = ra.getMenusInfo();
		String pageAuth = ra.getPageAuth();
		String folderInfo = ra.getFolderInfo();
		List<String> pas = StringUtils.isEmpty(pageAuth)? null:Arrays.asList(pageAuth.split("\\|"));
		userService.deleteRA(role);
		// 重新插入角色所有权限
		int res = 0;
		if (StringUtils.isNotEmpty(menusInfo) && !("|").equals(menusInfo)) {// 所选菜单非空
			String[] allMenu = menusInfo.split("\\|");
			for (String raMenu : allMenu) {
				if (StringUtils.isNotEmpty(raMenu)) {
					//menuInfo=" {{ menu.menuId+','+menu.menuType+','+menu.controllerCode }}"
					String raMenuId = raMenu.split(",")[0];
					String raMenuType = raMenu.split(",")[1];
					String raMenuControllerCode = raMenu.split(",")[2];
					StringBuffer raPageInfo = new StringBuffer();
					if(null != pas && pas.size()>0){
						pas.stream().filter(pa -> pa.startsWith(raMenuControllerCode+"_"))
								.forEach(pa -> {
								raPageInfo.append(pa).append("|");
//								pas.remove(pa);
						});
					}
					res += userService.insertRA(role, raMenuId, raMenuType, raMenuControllerCode,raPageInfo.toString());
				}
			}
		}
		if (StringUtils.isNotEmpty(folderInfo) && !("|").equals(folderInfo)) {// 半选中的菜单父级目录
			String[] allFolder = folderInfo.split("\\|");
			for(String raFolder:allFolder){
				if (StringUtils.isNotEmpty(raFolder)) {
					//menuInfo=" {{ menu.menuId+','+menu.menuType+','+menu.controllerCode }}"
					String raMenuId = raFolder.split(",")[0];
					String raMenuType = raFolder.split(",")[1];
					String raMenuControllerCode = raFolder.split(",")[2];
					res += userService.insertRA(role, raMenuId, raMenuType, raMenuControllerCode,"");
				}
			}
		}
		result.setRspData(res);
		return result;
	}

	@ResponseBody
	@RequestMapping(value = "/updateUR.do", produces = "application/json;charset=UTF-8")
	public PageResponse updateUR(String userId, String roles) throws Exception {
		PageResponse result = new PageResponse();
		logger.info("UserManageAction.updateUR: userId => " + userId + ";roles=>" + roles);
		int res = userService.updateUR(userId, roles);
		result.setRspData(res);
		return result;
	}

	@ResponseBody
	@RequestMapping(value = "/modifyRole.do", produces = "application/json;charset=UTF-8")
	public PageResponse modifyRole(RoleBean role) throws Exception {
		if (StringUtils.isNotEmpty(role.getRoleName())) {
			role.setRoleName(java.net.URLDecoder.decode(role.getRoleName(), "UTF-8"));
		}
		logger.info("UserManageAction.modifyRole: roleCode => " + role.getRoleCode() + ";roleName => "
				+ role.getRoleName() + ";");
		PageResponse result = new PageResponse();

		int optRes;
		if(StringUtils.isBlank(role.getRoleId())){
			optRes = userService.addRole(role);
		}else{
			optRes = userService.updateRole(role);
		}
		result.setRspData("成功修改"+optRes+"条角色信息");
		return result;
	}
	//====================================
	@ResponseBody
	@RequestMapping(value = "/updateMenu.do", produces = "application/json;charset=UTF-8")
	public Object updateMenu(UserBean user) throws Exception {
		CommonUtils.decodePara(user);
		logger.info("UserManageAction.updateMenu: user = " + JSON.toJSONString(user));
		Map<String, Object> res = new HashMap<>();
		int result = userService.updateMenu(user);
		if (result > 0) {
			res.put("msg", "修改成功,重新登陆时将生效");
		}
		return res;
	}

	@ResponseBody
	@RequestMapping(value = "/getCurrentUser.do", produces = "application/json;charset=UTF-8")
	public Object getCurrentUser(HttpServletRequest request, String fromState, String toState) throws Exception {
		logger.info("UserManageAction.getCurrentUser: fromState => " + fromState + ";toState =>" + toState);
		Map<String, Object> res = new HashMap<>();
		UserBean user = (UserBean) request.getSession().getAttribute("currentUser");
		logger.info("UserManageAction.getCurrentUser: currentUser => " + JSON.toJSONString(user));
		if (null == user) {
			res.put("userInfo", "");
			res.put("error", "no User");
		} else {
			res.put("userInfo", user);
			res.put("error", "");
			// 每次页面跳转都会请求过来获取登陆用户
			// 用来统计系统所有登陆用户
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Map<String, Object> loginUsers = MySessionListener.getAllSession();
			if (loginUsers.containsKey(request.getSession().getId())) {
				Map<String, Object> loginUser = (Map<String, Object>) loginUsers.get(request.getSession().getId());
				sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
				List<String> operations = new ArrayList<>();
				if (loginUser.containsKey("operations")) {
					operations = (List<String>) loginUser.get("operations");
				}
				operations.add(fromState + "=>" + toState + ";" + sdf.format(new Date()));
				loginUser.put("operations", operations);
				//发送websocket日志信息
				MyWebSocket.sendInfo("前台操作日志===》用户 "+user.getUserName()+" 从页面 "+fromState+" 跳转到  "+toState);
			}
		}
		return res;
	}

	@ResponseBody
	@RequestMapping(value = "/changePassword.do", produces = "application/json;charset=UTF-8")
	public Object changePassword(String userId, String oldPassword, String newPassword) throws Exception {
		logger.info("usermanage.changePassword: userId => " + userId + ";oldPassword =>" + oldPassword
				+ ";newPassword => " + newPassword);
		Map<String, String> res = new HashMap<>();
		int result = userService.updateUserPassword(userId, oldPassword, newPassword);
		if (result == 0) {
			res.put("code", "0");
			res.put("msg", "密码错误。");
		} else {
			res.put("code", "1");
			res.put("msg", "密码修改完成");
		}
		logger.info("usermanage.changePassword: res =>" + res.get("code") + ":" + res.get("msg"));
		return res;
	}

	@ResponseBody
	@RequestMapping(value = "/moveMenu.do", produces = "application/json;charset=UTF-8")
	public Object moveMenu() throws Exception {
		logger.info("UserManageAction.moveMenu");
		Map<String, Object> opRes = userService.moveMenu();
		String res = "共 " + opRes.get("userNum") + "	 个用户，共插入 " + opRes.get("authNum") + " 条权限数据";
		return res;
	}

	@RequestMapping(value = "/getMenuCount.do", produces = "application/json;charset=UTF-8")
	@Cacheable(value = "sysCache")
	public Object getMenuCount() throws Exception {
		logger.info("UserManageAction.getMenuCount");
		String menuCount = subMenuService.getMenuCount();
		Map<String, Object> res = new HashMap<>();
		res.put("menucount", menuCount);
		return res;
	}
}
